﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows;
using Facebook.Rest;
using Facebook.Schema;
using Facebook.Session;
using Facebook.Utility;

namespace TouchHelpers.Helper
{
    public class FacebookHelper : IShareHelper
    {
        private DesktopSession _session;
        private string _appKey = "d1dfde7111bbbdb4fa77bba5e0f32299";
        private string _appSecret = "e5922246b8aa64f9bfe06055aa9cb253";
        private static FacebookHelper _instance;
        private ConnectSession _connectSession;
        private Api _api;
        public event EventHandler UploadCompleted;

        public string LoginUrl
        {
            get
            {
                //return _session.GetLoginUrl();
                //return _session.GetLoginUrl().Replace("popup", "touch");
                return string.Format("http://www.facebook.com/login.php?api_key={0}&connect_display=touch&v=1.0&next=http://www.facebook.com/connect/login_success.html&cancel_url=http://www.facebook.com/connect/login_failure.html&type=user_agent&return_session=true&req_perms=read_stream,publish_stream", _appKey);
            }
        }

        public string LogOffUrl
        {
            get
            {
                return _api.LogOffUrl;
            }
        }

        public static FacebookHelper GetInstance()
        {
            if (_instance == null)
            {
                _instance = new FacebookHelper();
            }
            return _instance;
        }

        private FacebookHelper() 
        {
            _session = new DesktopSession(_appKey, null, null, true, new List<Enums.ExtendedPermissions> { Enums.ExtendedPermissions.read_stream, Enums.ExtendedPermissions.publish_stream });
        }

        public void Logout()
        {
            if (_session.SessionKey != null && _session.SessionSecret != null)
            {
                _api.Session.Logout();
                _api.Connect.Session.Logout();
            }
        }

        public void UploadMedia(MediaType mediaType, string path)
        {
            path = path.Replace("file:///", "");
            var fileInfo = new FileInfo(path);
            var fileStream = fileInfo.OpenRead();
            var fileStateObject = new FileStateObject
                                      {
                                          Bytes = new byte[fileInfo.Length],
                                          FileStream = fileStream,
                                          MediaType = mediaType,
                                          Api = _api,
                                          FileType = GetFileType(fileInfo)
                                      };
            fileStream.BeginRead(fileStateObject.Bytes, 0, fileStateObject.Bytes.Length, ReadCompleteCallback, fileStateObject);
        }

        private void ReadCompleteCallback(IAsyncResult ar)
        {
            var fileStateObject = ar.AsyncState as FileStateObject;
            fileStateObject.FileStream.EndRead(ar);
            switch (fileStateObject.MediaType)
            {
                case MediaType.Photo:
                    var albums = fileStateObject.Api.Photos.GetAlbums();
                    var album = albums.SingleOrDefault(a => a.name == "MTouch Share");
                    if (album == null)
                        album = fileStateObject.Api.Photos.CreateAlbum("MTouch Share", "", "Picture Uploaded from MTouch Application");
                    fileStateObject.Api.Photos.UploadAsync(album.aid, "Test picture From MTouch", fileStateObject.Bytes, fileStateObject.FileType, PictureUploadedCallBack, null);
                    break;
                case MediaType.Video:
                    fileStateObject.Api.Video.UploadAsync("Test Video from MTouch", "Uploaded from MTouch Application", fileStateObject.Bytes, fileStateObject.FileType, VideoUploadedCallback, null);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        private void VideoUploadedCallback(video video, object state, FacebookException e)
        {
            if (UploadCompleted != null)
                UploadCompleted(this, new EventArgs());
        }

        private void PictureUploadedCallBack(photo photo, object state, FacebookException e)
        {
            if (e != null)
                throw e;
            if (UploadCompleted != null)
                UploadCompleted(this, new EventArgs());
        }

        private static Enums.FileType GetFileType(FileInfo fileInfo)
        {
            switch (fileInfo.Extension)
            {
                case ".asf":
                    return Enums.FileType.asf;
                    break;
                case ".avi":
                    return Enums.FileType.avi;
                    break;
                case ".bmp":
                    return Enums.FileType.bmp;
                    break;
                case ".flv":
                    return Enums.FileType.flv;
                    break;
                case ".gif":
                    return Enums.FileType.gif;
                    break;
                case ".iff":
                    return Enums.FileType.iff;
                    break;
                case ".jp2":
                    return Enums.FileType.jp2;
                    break;
                case ".jpg":
                    return Enums.FileType.jpg;
                    break;
                case ".m4v":
                    return Enums.FileType.m4v;
                    break;
                case ".mkv":
                    return Enums.FileType.mkv;
                    break;
                case ".mov":
                    return Enums.FileType.mov;
                    break;
                case ".mp4":
                    return Enums.FileType.mp4;
                    break;
                case ".mpe":
                    return Enums.FileType.mpe;
                    break;
                case ".mpeg":
                    return Enums.FileType.mpeg;
                    break;
                case ".mpeg4":
                    return Enums.FileType.mpeg4;
                    break;
                case ".mpg":
                    return Enums.FileType.mpg;
                    break;
                case ".nsv":
                    return Enums.FileType.nsv;
                    break;
                case ".ogm":
                    return Enums.FileType.ogm;
                    break;
                case ".png":
                    return Enums.FileType.png;
                    break;
                case ".psd":
                    return Enums.FileType.psd;
                    break;
                case ".qt":
                    return Enums.FileType.qt;
                    break;
                case ".tiff":
                    return Enums.FileType.tiff;
                    break;
                case ".vob":
                    return Enums.FileType.vob;
                    break;
                case ".wbmp":
                    return Enums.FileType.wbmp;
                    break;
                case ".wmv":
                    return Enums.FileType.wmv;
                    break;
                case ".xbm":
                    return Enums.FileType.xbm;
                    break;
                default:
                    MessageBox.Show("File Type Not Supported by facebook");
                    return Enums.FileType.xbm;
            }
        }

        public void UpdateSession(string sessionKey, string uid, string expires, string secret, string sig)
        {
            _session.SessionKey = sessionKey;
            _session.SessionSecret = secret;
            _api = new Api(_session);
        }
    }
}
